﻿/**
 *******************************************************************************
 *                       Continental Confidential
 *                  Copyright (c) Continental AG. 2017
 *
 *      This software is furnished under license and may be used or
 *      copied only in accordance with the terms of such license.
 *******************************************************************************
 * @file    MainWindow.cpp
 * @brief   主窗口实现文件
 * @note    中文注释：实现MainWindow类的所有方法，负责插件加载、界面管理和插件交互
 *          English: Implementation file for MainWindow class, responsible for plugin loading, UI management and plugin interaction
 *******************************************************************************
 */
#include "MainWindow.h"
#include "ui_MainWindow.h"
#include "plugindialog.h"
#include "plugininterface/plugininterface.h"
#include <QDebug>
#include <QApplication>

static const char PLUGIN_PATH[] = "/plugins"; // 插件默认路径

/**
 * @brief MainWindow类构造函数
 * @param parent 父窗口指针，默认为nullptr
 * @details 初始化UI组件、应用程序设置和插件管理器
 *          配置插件路径并加载所有插件
 *          处理插件加载错误并设置必要的信号槽连接
 */
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow),
    m_setting(Q_NULLPTR)
{
    // TODO: Qt5.15.2升级 - QSettings构造函数需要显式指定格式，避免默认格式变更问题
    // 推荐: m_setting = new QSettings("ZXL1001", QSettings::IniFormat);
    ui->setupUi(this); // 初始化UI组件

    // 清空堆叠窗口中的默认部件
    QVector<QWidget *> vector;
    for(int i=0; i<ui->stackedWidget->count(); ++i)
    {
        vector.append(ui->stackedWidget->widget(i));
    }
    for(auto widget : vector)
    {
        ui->stackedWidget->removeWidget(widget);
    }

    // 创建应用程序设置对象
    m_setting = new QSettings("ZXL1001");

    // 配置插件路径
    QStringList plugingPath;
    plugingPath.append(qApp->applicationDirPath() + QLatin1String(PLUGIN_PATH));

    // TODO: Qt5.15.2升级 - PluginManager::instance()返回值需要使用智能指针管理
    // 连接插件管理器信号到槽函数
    // TODO: Qt5.15.2升级 - 信号槽语法应更新为新的函数指针语法
    connect(ExtensionSystem::PluginManager::instance(), SIGNAL(objectAdded(QObject*)),
            this, SLOT(pluginObjectAdded(QObject*)));

    // 配置插件管理器
    ExtensionSystem::PluginManager::setFileExtension(QLatin1String("pluginspec"));
    ExtensionSystem::PluginManager::setGlobalSettings(m_setting);
    ExtensionSystem::PluginManager::setPluginPaths(plugingPath);

    // 加载所有插件
    ExtensionSystem::PluginManager::loadPlugins();

    // 检查并处理插件加载错误
    if(ExtensionSystem::PluginManager::hasError())
    {
        ExtensionSystem::PluginErrorOverview errorOverview;
        errorOverview.exec();
        qApp->quit();
    }

    // 连接应用程序退出信号
    // TODO: Qt5.15.2升级 - 信号槽语法应更新为新的函数指针语法
    connect(this, SIGNAL(aboutToQuit()), &plgManager, SLOT(shutdown()));

} // TODO: Qt5.15.2升级 - 考虑使用成员初始化列表初始化更多成员变量
// C++17升级 - 考虑使用std::unique_ptr管理动态资源

/**
 * @brief MainWindow类析构函数
 * @details 释放UI资源和插件相关资源
 *          m_setting由插件管理器使用，不需要在此释放
 */
MainWindow::~MainWindow()
{
    delete ui; // 释放UI对象
}

/**
 * @brief 插件对象添加槽函数
 * @param obj 新增的插件对象指针
 * @details 当插件被加载并添加到系统时调用
 *          将插件界面添加到主窗口的堆叠部件中
 *          为特定插件设置示例MIME数据
 */
void MainWindow::pluginObjectAdded(QObject *obj)
{
    qDebug() << "插件已添加:" << obj; // 调试输出插件添加信息

    // 将对象转换为PluginInterFace类型
    PluginInterFace *item = dynamic_cast<PluginInterFace*>(obj);
    if(item != Q_NULLPTR)
    {
        QString pluginName = item->getPluginName();
        ui->listWidget->addItem(pluginName); // 添加插件名称到列表

        // 特殊处理BDSChannelOnePlugin插件
        if(pluginName == "BDSChannelOnePlugin")
        {
            // 设置字节数组类型的MIME数据
            item->setMimeData(MIMEDATA_TYPE::MIMEDATA_BYTEARRAY, "50,80,190,7,26,353,602,884,25,198,499");

            // TODO: Qt5.15.2升级 - 检查QImage构造函数路径格式是否需要修改
            // 注意: 此处使用了硬编码的Linux路径，在Windows系统上可能无法工作
            // 建议: 使用资源文件或相对路径
            item->setMimeData(MIMEDATA_TYPE::MIMEDATA_IMAGE, QImage("/home/zxl/Pictures/Screenshot from 2017-04-24 17:42:48.png"));
        }

        // 将插件部件添加到堆叠窗口
        QWidget * widget = item->getWidget();
        if(widget != Q_NULLPTR)
        {
            ui->stackedWidget->addWidget(widget);
        }
    }
}

/**
 * @brief 列表项双击槽函数
 * @param index 双击的列表项索引
 * @details 响应列表项双击事件，切换堆叠窗口中显示的插件界面
 *          通过索引行号设置当前显示的插件界面
 */
void MainWindow::on_listWidget_doubleClicked(const QModelIndex &index)
{
    // TODO: Qt5.15.2升级 - 考虑添加边界检查确保索引有效
    if(index.isValid() && index.row() < ui->stackedWidget->count())
    {
        ui->stackedWidget->setCurrentIndex(index.row());
    }
} // C++17升级 - 可使用std::clamp限制索引范围

/**
 * @brief 插件视图按钮点击槽函数
 * @details 响应插件视图按钮点击事件，打开插件管理对话框
 *          显示当前加载的插件信息
 */
void MainWindow::on_pluginViewBtn_clicked()
{
    qDebug() << "打开插件视图对话框"; // 调试输出

    // TODO: Qt5.15.2升级 - 使用智能指针管理对话框生命周期
    PluginDialog d(Q_NULLPTR);
    d.exec();
}
